home *** CD-ROM | disk | FTP | other *** search
- /*
- ARTemis (Graphic Editor for FM-TOWNS)
- (c) MATSUUCHI Ryosuke 1992,1993
-
- imageman.c
- Editing Image Manager(編集画像管理部)
-
- EIMnew EIM の初期化
- EIMdelete EIM の終了
-
- EIMresize 編集画像のサイズの変更
- EIMgetxbytes 編集画像バッファの1ラインのバイト数
- EIMadrs 指定座標に対応する編集画像バッファのアドレス
- EIMgetxsize 編集画像の大きさを得る
- EIMgetysize 編集画像の大きさを得る
- EIMdispon 画面表示も同時に行う
- EIMdispoff 画面表示は行わない
-
- EIMpset 編集画像上に点を打つ
- EIMline 直線を描く
- EIMhline 水平直線を描く
- EIMvline
- EIMboxline 矩形(枠)を描く
- EIMrboxline
- EIMboxfill
- EIMrboxfill filled 矩形を描く
- EIMgetblock 矩形イメージを切り出す
- EIMputblock 矩形イメージを貼りつける
- EIMpoint 指定した座標のカラーコード(パレット番号)を得る
- EIMpoint_back アンドゥーバッファ上のカラーコードを得る
-
- EIMgraypset
- EIMgrayhline
- EIMgrayhline_map
-
- EIMbackup 現在の編集画像をアンドゥーバッファに転送する
- EIMloadbackup アンドゥーバッファを現在の編集画像に
- */
-
- #include <stdio.h>
- #include <malloc.h>
- #include <memory.h>
- #include <msdos.cf>
- #include <stdlib.h>
- #include "ge.h"
- #include "dispman.h"
- #include "imageman.h"
- #include "mask.h"
- #include "subgrp.h"
-
-
- int graycol(int col1, int col2, int rate)
- {
- if(rate<0) rate=0; else if(rate>256) rate=256;
- if(rate==0)
- return col1;
- if(rate==256)
- return col2;
- short r1,g1,b1, r2,g2,b2, r3,g3,b3;
- r1 = (col1 >> 5) & 31;
- g1 = (col1 >> 10) & 31;
- b1 = col1 & 31;
- r2 = (col2 >> 5) & 31;
- g2 = (col2 >> 10) & 31;
- b2 = col2 & 31;
- short nr=256-rate;
- r3 = ((r1 * nr + r2 * (short)rate + 128) >> 8);
- g3 = ((g1 * nr + g2 * (short)rate + 128) >> 8);
- b3 = ((b1 * nr + b2 * (short)rate + 128) >> 8);
- if (r1==r3 && g1==g3 && b1==b3)
- {
- if (r2<r3) r3--; else if (r2>r3) r3++;
- if (g2<g3) g3--; else if (g2>g3) g3++;
- if (b2<b3) b3--; else if (b2>b3) b3++;
- }
- return (g3 << 10) + (r3 << 5) + b3;
- }
-
-
-
- static char *eibuf = NULL, *eibufbak = NULL;
- static int xsize,ysize;
- static int xbytes;
- #define IMAGE32K 0
- #define IMAGE16 1
- static int imagetype; // IMAGE32K, IMAGE16
- static bool dispsw;
-
-
- int EIMnew(int type, int xlen, int ylen)
- // type: 0=32Kcolors 1=16colors
- // xlen,ylen: 編集画像の大きさ(最小(320,240)(このときは1倍表示不可))
- {
- eibuf = malloc(xlen*ylen*2);
- eibufbak = malloc(xlen*ylen*2);
- memset(eibuf,0,xlen*ylen*2);
- memset(eibufbak,0,xlen*ylen*2);
- xsize = xlen, ysize = ylen;
- xbytes = xsize*2;
- imagetype = IMAGE32K;
- dispsw = YES;
- return 0;
- }
-
- void EIMdelete()
- {
- }
-
-
- int EIMresize(int xlen,int ylen)
- {
- return 0;
- }
-
- int EIMgetxbytes()
- {
- return xbytes;
- }
-
-
- char *EIMadrs(int x,int y)
- {
- if (imagetype == IMAGE32K)
- return eibuf + xbytes*y + x*2;
- else if (imagetype == IMAGE16)
- return eibuf + xbytes*y + x/2;
- }
-
- char *EIMadrs_back(int x,int y)
- {
- if (imagetype == IMAGE32K)
- return eibufbak + xbytes*y + x*2;
- else if (imagetype == IMAGE16)
- return eibufbak + xbytes*y + x/2;
- }
-
- int EIMgetxsize()
- {
- return xsize;
- }
-
- int EIMgetysize()
- {
- return ysize;
- }
-
-
- void EIMdispon()
- {
- dispsw = YES;
- DMimage_refresh();
- }
-
-
- void EIMdispoff()
- {
- dispsw = NO;
- }
-
-
- void EIMpset(int x, int y, int col, int op)
- {
- if (x < 0 || xsize <= x || y < 0 || ysize <= y)
- return;
- if (mask_chkxy(x,y))
- return;
- if (op == DrawNORMAL)
- {
- *(unsigned short*)(eibuf + xbytes*y + x*2) = col;
- if (dispsw)
- DMimage_pset(x,y,col,DrawNORMAL);
- }
- else if (op == DrawXOR)
- {
- *(unsigned short*)(eibuf + xbytes*y + x*2) ^= col;
- if (dispsw)
- DMimage_pset(x,y,col,DrawXOR);
- }
- }
-
-
- void EIMgraypset(int x,int y,int col,int gray)
- {
- if (gray == 256)
- {
- EIMpset(x,y,col,DrawNORMAL);
- return;
- }
- if (mask_chkxy(x,y))
- return;
- short *p = (short*)(eibuf + xbytes*y + x*2);
- col = graycol(*p, col, gray);
- *p = col;
- if (dispsw)
- DMimage_pset(x,y,col,DrawNORMAL);
- }
-
- void EIMgrayhline(int x1,int x2,int y,int col,int gray,bool conc_sw)
- {
- if (gray == 256)
- {
- EIMhline(x1,x2,y,col,DrawNORMAL);
- return;
- }
- if (x1 > x2)
- swap(x1,x2);
- short *p0 = (short*)(eibuf + xbytes*y + x1*2);
- if (!conc_sw || mixrate==256)
- {
- void hline(int _x1, int _x2, int _y)
- {
- short *p = p0 + _x1 - x1;
- for (int i=_x1; i<=_x2; i++,p++)
- *p = graycol(*p, col, gray);
- }
- hline_func(x1,x2,y,hline);
- }
- else
- {
- short *back_p0 = (short*)(eibufbak + xbytes*y + x1*2);
- char *cbufp;
- int py = -1;
- int mixr0 = getmixrate();
- void hline(int _x1, int _x2, int _y)
- {
- if (_y != py) // 濃度バッファ内でのアドレスの再計算の必要ありや?
- cbufp = cbuf_adrs(x1,_y), py=_y;
- short *p=p0+_x1-x1, *bp=back_p0+_x1-x1;
- for (int i=_x1; i<=_x2; i++,p++,bp++)
- {
- int t = cbuf_mix(cbuf2conc(cbufp[i-x1]), gray, mixr0);
- cbufp[i-x1] = conc2cbuf(t);
- *p = mixcol(*bp,col,t,NO);
- if (*p==*bp)
- {
- int oc = mixcol(*bp,col,mixr0,NO);
- int r=getR(*p),g=getG(*p),b=getB(*p);
- if(r<getR(oc)) r++; else if(r>getR(oc)) r--;
- if(g<getG(oc)) g++; else if(g>getG(oc)) g--;
- if(b<getB(oc)) b++; else if(b>getB(oc)) b--;
- *p = r*32+g*1024+b;
- }
- }
- }
- hline_func(x1,x2,y,hline);
- }
- if (dispsw)
- DMimage_hline_map(x1,x2,y,(char*)p0);
- }
-
- void EIMgrayhline_map(int x1,int x2,int y,int col,short int *graymap,
- bool conc_sw)
- {
- if (x1 > x2)
- swap(x1,x2);
- short *p0 = (short*)(eibuf + xbytes*y + x1*2);
- short *back_p0 = (short*)(eibufbak + xbytes*y + x1*2);
- if (!conc_sw)
- {
- void hline(int _x1, int _x2, int _y)
- {
- short *p = p0 + _x1-x1, *gp = graymap + _x1-x1;
- for (int i=_x1; i<=_x2; i++,p++,gp++)
- *p = (*gp==256?col:*gp==0?*p:graycol(*p, col, *gp));
- }
- hline_func(x1,x2,y,hline);
- }
- else
- {
- char *cbufp;
- int py = -1;
- int mixr0 = getmixrate();
- void hline(int _x1, int _x2, int _y)
- {
- if (_y != py) // 濃度バッファ内でのアドレスの再計算の必要ありや?
- cbufp = cbuf_adrs(x1,_y), py = _y;
- short *p = p0 + _x1-x1, *bp = back_p0 + _x1-x1;
- short *gp = graymap + _x1-x1;
- for (int i=_x1; i<=_x2; i++,p++,bp++,gp++)
- {
- if(*gp==0) continue;
- int t = cbuf_mix(cbuf2conc(cbufp[i-x1]), *gp, mixr0);
- cbufp[i-x1] = conc2cbuf(t);
- *p = mixcol(*bp,col,t,NO);
- if (*gp != 0 && *p == *bp)
- {
- int oc = mixcol(*bp,col,mixr0,NO);
- int r=getR(*p),g=getG(*p),b=getB(*p);
- if (r<getR(oc)) r++;
- else if (r>getR(oc)) r--;
- if (g<getG(oc)) g++;
- else if (g>getG(oc)) g--;
- if (b<getB(oc)) b++;
- else if (b>getB(oc)) b--;
- *p = r*32+g*1024+b;
- }
- }
- }
- hline_func(x1,x2,y,hline);
- }
- if (dispsw)
- DMimage_hline_map(x1,x2,y,(char*)p0);
- }
-
-
- void EIMline(int x1,int y1,int x2,int y2,int col,int op)
- {
- int x,y,xr,yr,r;
- xr = abs(x2-x1); yr = abs(y2-y1);
- if (xr == 0 && yr == 0)
- EIMpset(x1,y1,col,op);
- else if (xr > yr)
- {
- r = (yr * 65536) / xr;
- if (x2 < x1)
- { swap(x1,x2); swap(y1,y2); }
- if (y1 > y2)
- r = -r;
- x2 = _min(x2,xsize-1);
- for (x=x1,y=(y1<<16)+0x8000; x<=x2; x++,y+=r)
- EIMpset(x,y>>16,col,op);
- }
- else
- {
- r = (xr << 16) / yr;
- if (y2 < y1)
- { swap(x1,x2); swap(y1,y2); }
- if (x1 > x2)
- r = -r;
- y2 = _min(y2,ysize-1);
- for (y=y1,x=(x1<<16)+0x8000; y<=y2; y++,x+=r)
- EIMpset((x>>16),y,col,op);
- }
- }
-
-
- void EIMhline(int x1,int x2,int y,int col,int op) // 水平直線を描く
- {
- if (x1>x2)
- swap(x1,x2);
- int ix = x1;
- short *p = (short*)EIMadrs(x1,y);
- void hline(int _x1,int _x2,int _y)
- {
- if (op == DrawXOR)
- MEMstoreword_xor(getds(),(char*)(p+_x1-x1),col,(_x2-_x1+1));
- else
- MEMstoreword(getds(),(char*)(p+_x1-x1),col,(_x2-_x1+1));
- if (dispsw)
- DMimage_hline(_x1,_x2,_y,col,op);
- }
- hline_func(x1,x2,y,hline);
- }
-
-
- void EIMvline(int x,int y1,int y2,int col,int op) // 垂直直線を描く
- {
- if (y1>y2)
- swap(y1,y2);
- char *p = EIMadrs(x,y1);
- int i;
- if (op == DrawXOR)
- {
- int l = y2-y1+1;
- for (i=0; i<l; i++,p+=xbytes)
- if (!mask_chkxy(x,y1+i))
- { *(short*)p ^= col; if (dispsw) DMimage_pset(x,y1+i,col,op); }
- }
- else
- {
- int l = y2-y1+1;
- for (i=0; i<l; i++,p+=xbytes)
- if (!mask_chkxy(x,y1+i))
- { *(short*)p = col; if (dispsw) DMimage_pset(x,y1+i,col,op); }
- }
- //if (dispsw)
- // DMimage_vline(x,y1,y2,col,op);
- }
-
-
- void EIMboxline(int x1,int y1,int x2,int y2,int col,int op) // 矩形(枠)を描く
- {
- if (x1 > x2)
- swap(x1,x2);
- if (y1 > y2)
- swap(y1,y2);
- EIMhline(x1,x2,y1,col,op);
- if (y2 > y1)
- EIMhline(x1,x2,y2,col,op);
- if (y2 > y1+1)
- EIMvline(x1,y1+1,y2-1,col,op), EIMvline(x2,y1+1,y2-1,col,op);
- }
-
-
- void EIMrboxline(int x,int y,int xlen,int ylen,int col,int op) // 矩形(枠)を描く
- {
- EIMboxline(x,y,x+xlen-1,y+ylen-1,col,op);
- }
-
-
- void EIMrboxfill(int x1,int y1,int xlen,int ylen,int col,int op)
- {
- int i;
- for (i=0; i<ylen; i++)
- EIMhline(x1,x1+xlen-1,y1+i,col,op);
- }
-
-
- void EIMboxfill(int x1,int y1,int x2,int y2,int col,int op)
- {
- if (x1 > x2)
- swap(x1,x2);
- if (y1 > y2)
- swap(y1,y2);
- EIMrboxfill(x1,y1,x2-x1+1,y2-y1+1,col,op);
- }
-
-
- int EIMpoint(int x,int y)
- {
- if (x < 0 || y < 0 || xsize <= x || ysize <= y)
- return backcol;
- return (int)*(unsigned short*)(eibuf + xbytes*y + x*2);
- }
-
-
- int EIMpoint_back2(int x,int y)
- // x,y : 16ビット固定小数点
- {
- if (x < 0 || y < 0 || xsize <= (x>>16) || ysize <= (y>>16))
- return backcol;
- char *ep = eibufbak + xbytes*(y>>16) + (x>>16)*2;
- int px1,px2,py1,py2,w[4],c[4];
- px2 = (x>>8)&0xff; px1 = 256-px2;
- py2 = (y>>8)&0xff; py1 = 256-py2;
- x>>=16,y>>=16;
- w[0]=w[1]=w[2]=w[3]=0;
- if (0<=y && y<ysize)
- {
- if (0<=x && x<xsize)
- { if ((w[0] = (px1*py1+128)>>8) > 0) c[0] = *(short*)ep; }
- if (0<=x+1 && x+1<xsize)
- { if ((w[1] = (px2*py1+128)>>8) > 0) c[1] = *(short*)(ep+2); }
- }
- if (0<=y+1 && y+1<ysize)
- {
- if (0<=x && x<xsize)
- { if ((w[2] = (px1*py2+128)>>8) > 0) c[2] = *(short*)(ep+xbytes); }
- if (0<=x+1 && x+1<xsize)
- { if ((w[3] = (px2*py2+128)>>8)>0) c[3] = *(short*)(ep+xbytes+2); }
- }
- int mag,rgb[3],i;
- mag = 0, rgb[0]=rgb[1]=rgb[2]=0;
- for (i=0; i<4; i++)
- {
- if (w[i] > 0)
- {
- int ci=c[i],wi=w[i];
- mag+=wi;
- rgb[0]+=getR(ci)*wi, rgb[1]+=getG(ci)*wi, rgb[2]+=getB(ci)*wi;
- }
- }
- int h = mag/2;
- return GRB((rgb[1]+h)/mag, (rgb[0]+h)/mag, (rgb[2]+h)/mag);
- }
-
-
- int EIMpoint_back(int x,int y)
- {
- if (x < 0 || y < 0 || xsize <= x || ysize <= y)
- return backcol;
- return (int)*(unsigned short*)(eibufbak + xbytes*y + x*2);
- }
-
-
- void EIMgetblock(char *buf, int x,int y,int xlen,int ylen)
- {
- int i; char *p;
- p = buf;
- for (i=0; i<ylen; i++,p+=xlen*2)
- {
- // short *ep = (short*)EIMadrs(x,y+i);
- // for (j=0; j<xlen; j++)
- // *(short*)(p+j*2) = *(ep+j);
- memcpy(p, EIMadrs(x,y+i), xlen*2);
- }
- }
-
- void EIMputblock(int x,int y,int xlen,int ylen, char *buf, int op)
- {
- int i; char *p;
- p = buf;
- for (i=0; i<ylen; i++,p+=xlen*2)
- {
- int yi = y+i;
- if (yi < 0 || ysize <= yi)
- continue;
- int x1 = _max(x,0), x2 = _min(x+xlen-1,xsize-1);
- short *pp = (short*)EIMadrs(x1,yi);
- void hline(int _x1, int _x2, int _y)
- { memcpy(pp + _x1-x1, p + (_x1-x)*2, (_x2-_x1+1)*2); }
- hline_func(x1,x2,yi, hline);
- }
- if (dispsw)
- DMimage_refresh();
- }
-
-
- void EIMbackup() // 現在の編集画像をアンドゥーバッファに転送する
- {
- memcpy(eibufbak, eibuf, xsize*ysize*2);
- }
-
-
- void EIMloadbackup() // アンドゥーバッファを現在の編集画像に
- {
- memcpy(eibuf, eibufbak, xsize*ysize*2);
- if (dispsw)
- DMimage_refresh();
- }
-